package cn.xyinping.hrm.service.impl;

import cn.xyinping.hrm.constans.RedisConstans;
import cn.xyinping.hrm.domain.CourseType;
import cn.xyinping.hrm.mapper.CourseTypeMapper;
import cn.xyinping.hrm.service.ICourseTypeService;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 课程目录 服务实现类
 * </p>
 *
 * @author xyinping
 * @since 2021-11-26
 */
@Service
public class CourseTypeServiceImpl extends ServiceImpl<CourseTypeMapper, CourseType> implements ICourseTypeService {
    @Autowired
    private CourseTypeMapper courseTypeMapper;
    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;
    // 删除数据库，清空redis
    @Override
    @CacheEvict(cacheNames = RedisConstans.KEY_COURSE_TYPE_NAME, key = RedisConstans.KEY_COURSE_TYPE_TREE)
    public boolean insert(CourseType entity) {
        boolean success =  super.insert(entity);
//        if(success){
//                redisTemplate.delete(RedisConstants.KEY_ALL_COURSE_TYPE_TREE);
//        }
        return success;
    }

    @Override
    @CacheEvict(cacheNames = RedisConstans.KEY_COURSE_TYPE_NAME, key = RedisConstans.KEY_COURSE_TYPE_TREE)
    public boolean deleteById(Serializable id) {
        boolean success = super.deleteById(id);
//        if(success){
//            redisTemplate.delete(RedisConstans.KEY_COURSE_TYPE_TREE);
//        }
        return success;
    }

    @Override
    public boolean updateById(CourseType entity) {
        boolean success = super.updateById(entity);
 //        if(success){
//            redisTemplate.delete(RedisConstans.KEY_COURSE_TYPE_TREE);
//        }
        return success;
    }

    /**
     * resis缓存方式二：使用注解
     * @return
     */

    @Override
    @Cacheable(cacheNames = RedisConstans.KEY_COURSE_TYPE_NAME, key = RedisConstans.KEY_COURSE_TYPE_TREE)
    public List<CourseType> treeData() {
        // 走数据库
        return  list2treeFromDB();

    }

    @Override
    public void addTotalCourseByIds(int count, String[] Ids) {
        courseTypeMapper.addTotalCourseByIds(count, Ids);
    }
    /**
     * resis缓存
     * @return
     */
//    @Override
//    public List<CourseType> treeData() {
////        (1)先检查缓存是否有数据
//        List<CourseType> courseTypeTree = (List<CourseType>) redisTemplate.opsForValue().get(RedisConstans.KEY_COURSE_TYPE_TREE);
////        (2)如果缓存有，就直接返回
//        if(courseTypeTree !=null){
//            return courseTypeTree;
//        }
////        (3)如果没有，就查询数据库
////        (4)把数据库的数据转成treeDate
//        courseTypeTree = list2treeFromDB();
////        (5)把treedata放到缓存
//        redisTemplate.opsForValue().set(RedisConstans.KEY_COURSE_TYPE_TREE, courseTypeTree,12, TimeUnit.HOURS);
////        (6)返回数据
//        return courseTypeTree;
//    }

    /**
     * 课程分类树查询
     * 方式一：
            (1)查出第一层分类
            (2)循环每个第一层，查出第二层分类，添加第一层到children中
            (3)循环每个第二层，查出第三层分类，添加第二层到children中
            (4)如果固定层数，	使用for循环，
            (5)不固定层数就是用递归，我们这儿使用Mybatis的嵌套查询来做
        方式二：查询出所有分类，在代码中组装关系
            1. 查询所有分类
            2. 找出所有第一层
            3. 其他非第一层只需找各自的上一层，加入自己上一层children中
     */
    public List<CourseType> list2treeFromDB() {
        // 方式一：使用Mybatis的嵌套查询
        // return courseTypeMapper.selectTreeData(0L);
        // 方式二：从底层向第一层查询
        // 1. 查询所有分类
        List<CourseType> courseTypes = super.selectList(null);
        // 找出所有第一层
        List<CourseType> fristCourse = new ArrayList<>();
        courseTypes.forEach(courseType -> {
            // 如果pid为0就是第一层
            if(courseType.getPid()==null||courseType.getPid().longValue()==0){
                fristCourse.add(courseType);
            }else {
                // 其他非第一层只需找各自的上一层，加入自己上一层children中
                for (CourseType parentCourseTypes : courseTypes){
                    // 子类的pid如果等于父类id，就加入自己上一层children中
                    if(courseType.getPid().longValue()==parentCourseTypes.getId().longValue()){
                        parentCourseTypes.getChildren().add(courseType);
                    }
                }
            }
        });
            return fristCourse;
    }

}
